package com.mall.business.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.schema.ObjectSchema;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil;
import com.mall.business.domain.*;
import com.mall.business.enums.OrderStatus;
import com.mall.business.service.*;
import com.mall.business.service.impl.TOrderServiceImpl;
import com.mall.business.service.impl.TProductServiceImpl;
import com.mall.common.annotation.RepeatSubmit;
import com.mall.common.constant.CacheConstants;
import com.mall.common.core.controller.BaseController;
import com.mall.common.core.domain.AjaxResult;
import com.mall.common.core.domain.entity.SysUser;
import com.mall.common.core.page.TableDataInfo;
import com.mall.common.exception.ServiceException;
import com.mall.common.utils.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resources;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 订单接口
 */


@RestController
@RequestMapping("/webApiOrder")
public class ApiOrderController extends BaseController {


    @Autowired
    private ITUserAddressService tUserAddressService;


    @Autowired
    private ITCartService tCartService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private ITOrderService orderService;

    @Autowired
    private ITProductService productService;

    @Autowired
    private ITSeckillService tSeckillService;


    @Autowired
    private RedisLock redisLock;


    @Autowired
    private ITOrderPjService tOrderPjService;


    @Autowired
    private ITOrderItemService orderItemService;

    @Autowired
    private  ITOrderRefundService  orderRefundService;

    @Autowired
    private ITCouponService tCouponServie;


    /**
     * 订单评价
     */
    @RepeatSubmit
    @Transactional
    @PostMapping("/saveOrderPj")
    public AjaxResult saveOrderPj(@RequestBody List<TOrderPj> pjList) {
        String  orderNo= "";
        for (int i = 0; i <pjList.size() ; i++) {
            TOrderPj tOrderPj = pjList.get(i);
            String orderItemId = tOrderPj.getOrderItemId();
            TOrderItem orderitem = orderItemService.getById(orderItemId);
            if(StringUtil.isEmpty(orderNo)){
                orderNo = orderitem.getOrderNo();
            }
            String isComment = orderitem.getIsComment();
            if ("1".equals(isComment)) {
                return AjaxResult.error("您已经评价过了");
            }
            tOrderPj.setOrderNo(orderitem.getOrderNo());
            tOrderPj.setUserId(SecurityUtils.getUserIdStr());
            tOrderPjService.save(tOrderPj);
            orderitem.setIsComment("1");
            orderItemService.updateById(orderitem);
        }
        TOrder orderByOrderNo = orderService.getOrderByOrderNo(orderNo);
        orderByOrderNo.setIsComment("1");
        orderService.updateById(orderByOrderNo);
        return AjaxResult.success();
    }


    /**
     * 用户参与秒杀
     */
    @PostMapping("/userSeckill")
    public AjaxResult seckill(@RequestBody UserSeckillDTO dto) {
        String seckillId = dto.getSkillId();
        //(1)拿到锁的对象
        RLock room_lock = redisLock.getRLock(seckillId);
        // 尝试获取锁，参数分别是 ：获取锁的最大等待时间 （期间会重试），锁自动释放时间，时间单位
        // 2秒钟 还是没有获取锁 就返回false
        // 3. 尝试加锁，最多等待3秒，上锁以后10秒自动解锁
        boolean isLock = false;
        try {
            isLock = room_lock.tryLock(3, 10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new ServiceException("服务器正忙！");
        }
        if (isLock) {
            try {
                TProduct tProduct = orderService.userSkill(seckillId);
                return AjaxResult.success(tProduct);
            } finally {
                if (room_lock.isLocked()) {
                    room_lock.unlock();
                }
            }
        } else {
            throw new ServiceException("服务器正忙！");
        }


    }


    /**
     * 生成订单----去结算
     */
    @PostMapping("/confirm")
    public AjaxResult confirm(@Valid @RequestBody OrderParam orderParam) {
        // 获得用户地址
        TUserAddress userMrAddress = tUserAddressService.getUserMrAddress();
//        if (userMrAddress == null) {
//            throw new ServiceException("请配置默认地址");
//        }
        // 组装获取用户提交的购物车商品项
        List<TCart> shopCartItems = tCartService.getShopCartItemsByOrderItems(orderParam.getBasketIds(), orderParam.getOrderItem());
        if (CollectionUtil.isEmpty(shopCartItems)) {
            throw new ServiceException("请选择您需要的商品加入购物车");
        }
        // 将要返回给前端的完整的订单信息
        OrderMergeDTO orderMergeDTO = new OrderMergeDTO();
        // 地址信息
        orderMergeDTO.setUserAddress(userMrAddress);
        // 总金额
        BigDecimal totalPrice = BigDecimal.ZERO;
        Long totalCount = 0L;
        for (TCart shopCart : shopCartItems) {
            // 总金额 计算
            totalPrice = totalPrice.add(shopCart.getProductPrice().multiply(new BigDecimal(shopCart.getCartNum())));
            // 总数量
            totalCount = totalCount + shopCart.getCartNum();
        }
        // 总金额
        orderMergeDTO.setTotalPrice(totalPrice);
        // 总数量
        orderMergeDTO.setTotalNum(totalCount);
        // 每个店铺的购物车 数据
        orderMergeDTO.setCartOrders(shopCartItems);
        String comfirmOrderkey = CacheConstants.CONFIRM_ORDER_KEY + SecurityUtils.getUserIdStr();
        // 讲 订单数据 放入 ---缓存
        redisService.setCacheObject(comfirmOrderkey, orderMergeDTO, 10L, TimeUnit.MINUTES);
        return AjaxResult.success(orderMergeDTO);
    }



    /**
     * 购物车/立即购买  提交订单,根据店铺拆单
     */
    @Transactional
    @PostMapping("/submitOrders")
    public AjaxResult submitOrders(@RequestBody OrderParam orderParam) {
        String addressId = orderParam.getAddressId();
        String comfirmOrderkey = CacheConstants.CONFIRM_ORDER_KEY + SecurityUtils.getUserIdStr();
        ObjectMapper objectMapper = new ObjectMapper();
        OrderMergeDTO mergerOrder = objectMapper.convertValue(redisService.getCacheObject(comfirmOrderkey), OrderMergeDTO.class);
        if (mergerOrder == null) {
            throw new ServiceException("订单已过期，请重新下单");
        }
        if (StringUtil.isEmpty(addressId) && mergerOrder.getUserAddress() == null) {
            throw new ServiceException("请选择订单地址");
        }
        if (!StringUtil.isEmpty(addressId)) {
            TUserAddress userAddress = tUserAddressService.getById(addressId);
            mergerOrder.setUserAddress(userAddress);
        }
        // 优惠券Id
        String couponId = orderParam.getCouponId();
        if(StringUtil.isNotEmpty(couponId)){
            TCoupon coupon = tCouponServie.getById(couponId);
            // 优惠券校验
            orderService.couponValidate(coupon);
            mergerOrder.setCouponId(couponId);
            mergerOrder.setCouponPrice(coupon.getMoney());
        }
        // 备注
        String remark = orderParam.getRemark();

        // 商品skuId为key 需要更新的sku为value的map  ------空间规格
        Map<String, TProduct> kjskuStocksMap = new HashMap<>(16);
        // 生成订单
        String orderNo = orderService.createOrder(mergerOrder,remark,kjskuStocksMap);

        kjskuStocksMap.forEach((key, sku) -> {
            if (productService.updateStocks(sku) == 0) {
                throw new ServiceException("商品：[" + sku.getTitle() + "]库存不足");
            }
        });
        // 清除缓存
        if (redisService.hasKey(comfirmOrderkey)) {
            redisService.deleteObject(comfirmOrderkey);
        }
        return AjaxResult.success(orderNo);
    }

    /**
     * 我的订单
     */
    @GetMapping("/getOrderList")
    public TableDataInfo getOrderList(TOrder order) {
        startPage();
        order.setUserId(SecurityUtils.getUserIdStr());
        List<TOrder> tOrders = orderService.selectTOrderListApp(order);
        return getDataTable(tOrders);
    }


    /**
     *
     * 订单详情
     *
     */
    @GetMapping("/getOrderDetail")
    public AjaxResult getOrderDetail(@RequestParam(value = "orderNo") String orderNo) {
        OrderShopDto orderShopDto = new OrderShopDto();
        TOrder order_old =orderService.getOrderByOrderNo(orderNo);
        if (order_old == null) {
            throw new RuntimeException("该订单不存在");
        }
        List<TOrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(order_old.getOrderNo());
        orderShopDto.setOrderdto(order_old);
        orderShopDto.setOrderItemDtos(orderItems);
        return AjaxResult.success(orderShopDto);
    }
    /**
    *
    * 取消订单
    *
    *
    */
    @PutMapping("/cancel/{orderId}")
    public AjaxResult cancel(@PathVariable("orderId") String orderId) {
        String userId = SecurityUtils.getUserIdStr();
        TOrder order_old = orderService.getById(orderId);
        if (order_old == null) {
            throw new ServiceException("该订单不存在");
        }
        if (!java.util.Objects.equals(order_old.getUserId(), userId)) {
            throw new ServiceException("你没有权限获取该订单信息");
        }
        if (!java.util.Objects.equals(order_old.getOrderStatus(), OrderStatus.UNPAY.value())) {
            throw new ServiceException("订单状态不正确");
        }
        order_old.setOrderStatus(OrderStatus.CLOSE.value());
        order_old.setCancelTime(DateUtils.getNowDate());
        order_old.setCloseType("2");
        orderService.updateById(order_old);
        // 恢复库存
        List<TOrderItem> orderItemsByOrderNumber = orderItemService.getOrderItemsByOrderNumber(order_old.getOrderNo());
        for (TOrderItem orderItem : orderItemsByOrderNumber) {
            TProduct product = productService.getById(orderItem.getProductId());
            if(product.getStock()==null){
                product.setStock(orderItem.getPayNum());
                productService.updateById(product);
            }else{
                product.setStock(product.getStock() + orderItem.getPayNum());
                productService.updateById(product);
            }

        }

        return AjaxResult.success();
    }



    /**
     *
     *
     * 确认收货
     *
     */
    @PostMapping("/updateOrderArrival")
    public AjaxResult updateOrderArrival(@Valid @RequestBody ArrivalOrderParam arrivalOrderParam) {
        TOrder order_old = orderService.getById(arrivalOrderParam.getOrderId());
        String userIdStr = SecurityUtils.getUserIdStr();
        if (!userIdStr.equals(order_old.getUserId())) {
            throw new ServiceException("您没有权限修改该订单信息");
        }
        if (!java.util.Objects.equals(order_old.getOrderStatus(), OrderStatus.CONSIGNMENT.value())) {
            throw new ServiceException("订单未发货，无法确认收货");
        }
        // 确认收货
        order_old.setOrderStatus(OrderStatus.CONFIRM.value());
        order_old.setFinallyTime(DateUtils.getNowDate());
        orderService.updateById(order_old);
        return AjaxResult.success();
    }


    /**
     *
     *
     * 售后申请
     *
     */
    @PostMapping("/refoundSq")
    @Transactional
    @RepeatSubmit
    public AjaxResult refoundSq( @RequestBody List<TOrderRefund> refundList) {
        for (int i = 0; i < refundList.size(); i++) {
            TOrderRefund vo = refundList.get(i);
            TOrderItem orderitem = orderItemService.getById(vo.getOrderItemId());
            String refundStatus = orderitem.getRefundStatus();
            if(!"0".equals(refundStatus)){
                throw  new ServiceException("该订单商品已申请售后");
            }
            TOrder orderByOrderNo = orderService.getOrderByOrderNo(orderitem.getOrderNo());
            String productId = orderitem.getProductId();
            TProduct product = productService.getById(productId);
            TOrderRefund  orderRefund =new TOrderRefund();
            orderRefund.setOrderId(vo.getOrderId());
            orderRefund.setOrderItemId(vo.getOrderItemId());
            orderRefund.setRefundNum(orderitem.getPayNum());
            orderRefund.setUserId(SecurityUtils.getUserIdStr());
            orderRefund.setOrderNumber(orderitem.getOrderNo());
            orderRefund.setCheckStatus("1");
            // 处理中
            orderRefund.setReturnStatus("1");
            // 退货原因
            orderRefund.setRefoundType(vo.getRefoundType());
            // 其他原因
            orderRefund.setBuyerMsg(vo.getBuyerMsg());
            // 支付方式
            orderRefund.setPayType(orderByOrderNo.getPayType());
            // 申请时间
            orderRefund.setApplyTime(DateUtils.getNowDate());
            orderRefund.setProductId(productId);
            orderRefund.setProductTitle(product.getTitle());
            orderRefund.setProductInfo(product.getInfo());
            orderRefund.setProductImage(product.getImage());
            orderRefund.setProductPrice(orderitem.getTotalPrice());
            orderRefundService.save(orderRefund);
            // 退货处理中
            orderitem.setRefundStatus("1");
            orderItemService.updateById(orderitem);
        }

        return AjaxResult.success();
    }


}
